1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#![allow(non_camel_case_types, non_snake_case)]

use crate::co;
use crate::decl::*;
use crate::gdi::ffi;
use crate::guard::*;
use crate::kernel::privs::*;
use crate::prelude::*;

impl GdiObject for HBRUSH {}
impl gdi_Hbrush for HBRUSH {}

/// This trait is enabled with the `gdi` feature, and provides methods for
/// [`HBRUSH`](crate::HBRUSH).
///
/// Prefer importing this trait through the prelude:
///
/// ```no_run
/// use winsafe::prelude::*;
/// ```
pub trait gdi_Hbrush: Handle {
	/// Creates a brush with the given system color.
	///
	/// **Note:** This should be used only to initialize the
	/// [`WNDCLASSEX`](crate::WNDCLASSEX)'s `hbrBackground` field. Any other use
	/// will yield an invalid handle.
	#[must_use]
	fn from_sys_color(color: co::COLOR) -> HBRUSH {
		unsafe { HBRUSH::from_ptr((color.raw() + 1) as _ ) }
	}

	/// [`CreateBrushIndirect`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createbrushindirect)
	/// function.
	#[must_use]
	fn CreateBrushIndirect(
		lb: &LOGBRUSH,
	) -> SysResult<DeleteObjectGuard<HBRUSH>>
	{
		unsafe {
			ptr_to_sysresult_handle(ffi::CreateBrushIndirect(lb as *const _ as _))
				.map(|h| DeleteObjectGuard::new(h))
		}
	}

	/// [`CreateHatchBrush`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createhatchbrush)
	/// function.
	#[must_use]
	fn CreateHatchBrush(
		hatch: co::HS,
		color: COLORREF,
	) -> SysResult<DeleteObjectGuard<HBRUSH>>
	{
		unsafe {
			ptr_to_sysresult_handle(
				ffi::CreateHatchBrush(hatch.raw(), color.into()),
			).map(|h| DeleteObjectGuard::new(h))
		}
	}

	/// [`CreatePatternBrush`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createpatternbrush)
	/// function.
	#[must_use]
	fn CreatePatternBrush(
		hbmp: &HBITMAP,
	) -> SysResult<DeleteObjectGuard<HBRUSH>>
	{
		unsafe {
			ptr_to_sysresult_handle(ffi::CreatePatternBrush(hbmp.ptr()))
				.map(|h| DeleteObjectGuard::new(h))
		}
	}

	/// [`CreateSolidBrush`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-createsolidbrush)
	/// function.
	#[must_use]
	fn CreateSolidBrush(
		color: COLORREF,
	) -> SysResult<DeleteObjectGuard<HBRUSH>>
	{
		unsafe {
			ptr_to_sysresult_handle(ffi::CreateSolidBrush(color.into()))
				.map(|h| DeleteObjectGuard::new(h))
		}
	}

	/// [`GetObject`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getobjectw)
	/// function.
	///
	/// # Examples
	///
	/// ```no_run
	/// use winsafe::{self as w, prelude::*};
	///
	/// let hbr: w::HBRUSH; // initialized somewhere
	/// # let hbr = w::HBRUSH::NULL;
	///
	/// let mut brush = w::LOGBRUSH::default();
	/// hbr.GetObject(&mut brush)?;
	/// # w::SysResult::Ok(())
	/// ```
	fn GetObject(&self, pv: &mut LOGBRUSH) -> SysResult<()> {
		match unsafe {
			ffi::GetObjectW(
				self.ptr(),
				std::mem::size_of::<LOGBRUSH>() as _,
				pv as *mut _ as _,
			)
		} {
			0 => Err(GetLastError()),
			_ => Ok(()),
		}
	}

	/// [`GetStockObject`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getstockobject)
	/// function.
	#[must_use]
	fn GetStockObject(sb: co::STOCK_BRUSH) -> SysResult<HBRUSH> {
		ptr_to_sysresult_handle(unsafe { ffi::GetStockObject(sb.raw()) })
	}

	/// [`GetSysColorBrush`](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsyscolorbrush)
	/// function.
	#[must_use]
	fn GetSysColorBrush(index: co::COLOR) -> SysResult<HBRUSH> {
		ptr_to_sysresult_handle(unsafe { ffi::GetSysColorBrush(index.raw()) })
	}

	/// [`UnrealizeObject`](https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-unrealizeobject)
	/// function.
	fn UnrealizeObject(&self) -> SysResult<()> {
		bool_to_sysresult(unsafe { ffi::UnrealizeObject(self.ptr()) })
	}
}